import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'photo_asset.dart';
import 'photo_kit.dart';

class PhotoDataProvider extends ImageProvider {
  const PhotoDataProvider({
    @required this.photo,
    this.bytes,
    this.scale = 1.0,
    this.width = -1,
    this.height = -1,
  });

  final PhotoAsset photo;

  final int width;

  final int height;

  final double scale;

  final Uint8List bytes;

  @override
  ImageStreamCompleter load(key, decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(key, decode),
      scale: key.scale,
      informationCollector: () sync* {
        yield ErrorDescription('photoId: $photo');
      },
    );
  }

  Future<ui.Codec> _loadAsync(
    PhotoDataProvider key,
    DecoderCallback decode,
  ) async {
    assert(key == this);
    Uint8List _bytes = bytes;
    if (_bytes == null)
      _bytes = await PhotoKit.requestImageData(
        photo.identity,
        width: width,
        height: height,
      );
    if (_bytes == null || _bytes.lengthInBytes == 0)
      throw '无法加载图片${photo.identity}';

    return await ui.instantiateImageCodec(_bytes, targetWidth: width);
  }

  @override
  bool operator ==(dynamic other) {
    if (!(other is PhotoDataProvider)) return false;

    final PhotoDataProvider otherPhoto = other;
    bool isNeedReDecode = true &&
        otherPhoto.width != null &&
        width != null &&
        otherPhoto.width != width;

    return true &&
        photo.identity == otherPhoto.photo.identity &&
        !isNeedReDecode;
  }

  @override
  int get hashCode => ui.hashValues(photo.identity, width);

  @override
  Future obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<PhotoDataProvider>(this);
  }
}
